package com.yanqu.road.dao.impl.player;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.yanqu.road.dao.db.DbNameStrategy;
import com.yanqu.road.dao.impl.TempDataObjectDao;
import com.yanqu.road.entity.disperseGold.DisperseGoldInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class DisperseGoldDaoImpl extends TempDataObjectDao<DisperseGoldInfo> {

    public Long getMaxDisperseId(long serverId) {
        String sql = "select ifnull(max(disperseId),0) as maxId from t_u_disperse_gold where serverId = ?";
        ResultSet rs = null;
        CallableStatement call = null;
        long maxId = 0L;
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            call.setLong(1, serverId);
            rs = call.executeQuery();
            while (rs.next()) {
                maxId = rs.getLong("maxId");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return maxId;
    }

    public Map<Long, List<DisperseGoldInfo>> getDisperseGoldMap() {
        ResultSet rs = null;
        CallableStatement call = null;
        Map<Long, List<DisperseGoldInfo>> dataMap = new ConcurrentHashMap<>();
        String sql = "select * from t_u_disperse_gold where sendEmail = 0";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareCall(sql);
            rs = call.executeQuery();
            while (rs.next()) {
                DisperseGoldInfo data = parse(rs);
                if (!dataMap.containsKey(data.getUserId())) {
                    dataMap.put(data.getUserId(), new ArrayList<>());
                }
                dataMap.get(data.getUserId()).add(data);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            getDb().closeConnection(call, rs);
        }
        return dataMap;
    }

    @Override
    protected boolean addData(DisperseGoldInfo data) {
        PreparedStatement call = null;
        String sql = "insert into t_u_disperse_gold(disperseId,userId,beginTime,reward,manifesto,sendEmail,playerNum,honoraryTitles,serverId," +
                "earnSpeed,userBaseInfo,channelId,assistantSkin,badge,privilege) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setLong(i++, data.getDisperseId());
            call.setLong(i++, data.getUserId());
            call.setLong(i++, data.getBeginTime());
            call.setString(i++, data.getReward());
            call.setString(i++, data.getManifesto());
            call.setBoolean(i++, data.isSendEmail());
            call.setInt(i++, data.getPlayerNum());
            call.setString(i++, data.getHonoraryTitles());
            call.setLong(i++, data.getServerId());
            call.setString(i++, data.getEarnSpeed().toString());
            call.setString(i++, data.getUserBaseInfoJsonString());
            call.setInt(i++, data.getChannelId());
            call.setString(i++, data.getAssistantSkin());
            call.setString(i++, data.getBadge());
            call.setString(i++, data.getPrivilege());
            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected boolean updateData(DisperseGoldInfo data) {
        PreparedStatement call = null;
        String sql = "update t_u_disperse_gold SET userId=?,beginTime=?,reward=?,manifesto=?,sendEmail=?,playerNum=?,honoraryTitles=?," +
                "serverId=?,earnSpeed=?,userBaseInfo=?,channelId=?,assistantSkin = ?,badge = ?,privilege = ? where disperseId=?";
        try {
            getDb().setConnName(DbNameStrategy.getUserDb());
            call = getDb().getConnection().prepareStatement(sql);
            int i = 1;
            call.setLong(i++, data.getUserId());
            call.setLong(i++, data.getBeginTime());
            call.setString(i++, data.getReward());
            call.setString(i++, data.getManifesto());
            call.setBoolean(i++, data.isSendEmail());
            call.setInt(i++, data.getPlayerNum());
            call.setString(i++, data.getHonoraryTitles());
            call.setLong(i++, data.getServerId());
            call.setString(i++, data.getEarnSpeed().toString());
            call.setString(i++, data.getUserBaseInfoJsonString());
            call.setInt(i++, data.getChannelId());
            call.setString(i++, data.getAssistantSkin());
            call.setString(i++, data.getBadge());
            call.setString(i++, data.getPrivilege());
            call.setLong(i++, data.getDisperseId());
            return call.executeUpdate() > 0;
        } catch (Exception e) {
            logger.error(Thread.currentThread().getStackTrace()[1].getMethodName() + ":", e);
        } finally {
            getDb().closeConnection(call, null);
        }
        return false;
    }

    @Override
    protected DisperseGoldInfo parseData(ResultSet rs) throws SQLException {
        DisperseGoldInfo data = new DisperseGoldInfo();
        data.setDisperseId(rs.getLong("disperseId"));
        data.setUserId(rs.getLong("userId"));
        data.setBeginTime(rs.getLong("beginTime"));
        data.setReward(rs.getString("reward"));
        data.setManifesto(rs.getString("manifesto"));
        data.setSendEmail(rs.getBoolean("sendEmail"));
        data.setPlayerNum(rs.getInt("playerNum"));
        data.setHonoraryTitles(rs.getString("honoraryTitles"));
        data.setServerId(rs.getLong("serverId"));
        data.setAssistantSkin(rs.getString("assistantSkin"));
        data.setBadge(rs.getString("badge"));
        String value = rs.getString("earnSpeed");
        if(!StringUtils.isNullOrEmpty(value)) {
            data.setEarnSpeed(new BigInteger(value));
        }
        value = rs.getString("userBaseInfo");
        if(!StringUtils.isNullOrEmpty(value)){
            UserBaseInfo userBaseInfo = JSON.parseObject(value, new TypeReference<UserBaseInfo>() {});
            if(null != userBaseInfo) {
                data.setUserBaseInfo(userBaseInfo);
            }
        }
        data.setChannelId(rs.getInt("channelId"));
        String privilege = rs.getString("privilege");
        if(privilege == null){
            data.setPrivilege("");
        }else {
            data.setPrivilege(privilege);
        }
        return data;
    }
}
